Skip to content

Add startup health check to prevent silent scheduler failure on non-default PORT - #665

Merged
joryirving merged 3 commits into
mainfrom
foreman/wl-misospace-dispatch-653/issue-653
Jul 29, 2026
Merged

Add startup health check to prevent silent scheduler failure on non-default PORT#665
joryirving merged 3 commits into
mainfrom
foreman/wl-misospace-dispatch-653/issue-653

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

What

Fixes PORT resolution in the in-app scheduler to properly handle empty/whitespace values, and adds a startup health check that verifies the scheduler can reach its own /api/health endpoint before arming periodic jobs.

Why

The scheduler previously used `env.PORT |…

Fixes #653

Opened by foreman on review GO (workload wl-misospace-dispatch-653).

@itsmiso-ai
itsmiso-ai requested a review from joryirving as a code owner July 25, 2026 08:37
its-saffron[bot]

This comment was marked as outdated.

…efault PORT

The scheduler now calls a new `schedulerHealthCheck` function at startup which
fetches `/api/health` using the configured bearer token. This verifies the
scheduler can reach its own endpoints before periodic jobs begin firing.

The health check returns true on HTTP 200 and false otherwise, logging
descriptive errors via the injected deps.log. It does not prevent the scheduler
from running — it provides visibility into misconfiguration without blocking
periodic work.

Fixes #653

Signed-off-by: Saffron <263493777+itsmiso-ai@users.noreply.github.com>
@itsmiso-ai
itsmiso-ai force-pushed the foreman/wl-misospace-dispatch-653/issue-653 branch from 3ef034c to 67cb1b4 Compare July 25, 2026 11:02
@its-saffron
its-saffron Bot dismissed their stale review July 25, 2026 11:08

Superseded by a newer automated review for this pull request.

its-saffron[bot]

This comment was marked as outdated.

Address review feedback on #665 — health check was inside the per-job
loop, causing N checks at startup instead of one.

@its-saffron its-saffron Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Automated Review

Full PR review.

Analysis engine: MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) — escalated (fast_low_confidence)

Recommendation: Approve

This PR adds a startup health check to the in-app scheduler that verifies it can reach its own /api/health endpoint before arming periodic jobs. The change is minimal, well-tested, and satisfies the linked issue's acceptance criteria.

Change-by-Change Findings

src/lib/scheduler.ts (+31 lines)

  • schedulerHealthCheck: New exported async function that fetches ${config.baseUrl}/api/health with bearer auth. Returns true on HTTP 200, false otherwise. Uses the repository's canonical error instanceof Error pattern for error handling and logs descriptive failure messages (HTTP status code or exception message).
  • startScheduler: Injects one additional setTimeout call (at the same config.startupDelayMs as job timers) to fire schedulerHealthCheck once at startup, outside the per-job loop. The check is non-blocking — it does not prevent periodic work from arming.

src/lib/scheduler.test.ts (+42, -7 lines)

  • Updates the existing startScheduler test to assert two setTimeout calls (health check + job) and fires both callbacks before asserting.
  • New describe("schedulerHealthCheck") block with three cases: happy-path 200 → true, non-ok status → false with log, fetch throws → false with log and error.

Standards Compliance

Standard Status
Error handling — error instanceof Error pattern ✅ Used in schedulerHealthCheck catch block
Bearer token auth for internal endpoints Authorization: Bearer ${config.token} matches existing scheduler auth model
No secrets in logs ✅ Only config.token used for auth header; token value not echoed
API returns appropriate HTTP status / JSON schedulerHealthCheck is an internal helper, not an HTTP route; existing health route is unchanged
Validation before DB operations ✅ N/A — this function makes an HTTP call, not a DB call

Linked Issue Fit

Issue PR 653 acceptance criteria:

Criterion Verification
Use 127.0.0.1:${port} consistently with port resolved from PORT env schedulerConfigFromEnv (existing code) builds baseUrl as http://127.0.0.1:${port} where `port = env.PORT?.trim()
Add a startup health check that verifies the scheduler can reach its own endpoints schedulerHealthCheck fires once via setTimeout at startupDelayMs (5s default) before jobs arm. It calls /api/health with bearer auth and logs failures.

Tool Harness Findings

The harness confirmed:

  • src/lib/scheduler.ts and src/lib/scheduler.test.ts match the diff content.
  • schedulerConfigFromEnv already constructs baseUrl correctly from PORT env (http://127.0.0.1:8080 when PORT=8080).
  • /api/health is listed in middleware.ts as always-public (no auth required), so the health check will succeed regardless of auth mode.

CI Check Results

All CI checks passed at commit c9fdc7b9e5d9b65e477d55f166d890ec0f334a6c:

  • ✅ Typecheck
  • ✅ Tests
  • ✅ Lint
  • ✅ Build
  • ✅ Docker Build

Unknowns or Needs Verification

None — the diff is self-contained, the implementation is internally consistent with the existing scheduler pattern, and all acceptance criteria from the linked issue are addressed.

@joryirving
joryirving merged commit 2eda69b into main Jul 29, 2026
6 checks passed
@joryirving
joryirving deleted the foreman/wl-misospace-dispatch-653/issue-653 branch July 29, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P2] Prevent silent scheduler failure on non-default PORT

2 participants